﻿using System;

namespace rehot
{
    using rehot.core;

    public class HotObject : IDisposable
    {
        public static HotObject Null = new HotObject();
        public bool IsNull { get { return this._obj == null; } }
        internal HotType _hottype { get; set; }
        internal object _obj { get; set; }
        internal HotObject() { }
        public HotObject(HotType hotType, object obj)
        {
            this._hottype = hotType;
            this._obj = obj;
        }
        public HotObject(object obj)
        {
            this._hottype = new HotType(obj.GetType());
            this._obj = obj;
        }
        public HotType Type { get { return this._hottype; } }
        public HotObject UseObject(object obj)
        {
            this._obj = obj;
            return this;
        }
        public bool ExistMember(string name)
        {
            return this._hottype.Members.Exist(name);
        }
        public bool ExistMethod(string name, params IHotParam[] _params)
        {
            return this._hottype.Methods.Exist(name, _params);
        }
        public bool ExistEvent(string name)
        {
            return this._hottype.Events.Exist(name);
        }
        public string FindMemberId(string name)
        {
            return this._hottype.Members.FindMemberId(name);
        }
        public HotObject ReadByMemberId(string id)
        {
            return this._hottype.Members.GetUnknownByMemberId(_obj, id);
        }
        public object ReadObjByMemberId(string id)
        {
            return this._hottype.Members.GetByMemberId(_obj, id);
        }
        public Tout ReadByMemberId<Tout>(string id)
        {
            return this._hottype.Members.GetByMemberId<Tout>(_obj, id);
        }
        public void WriteByMemberId<Tin>(string id, Tin value)
        {
            this._hottype.Members.SetByMemberId<Tin>(_obj, id, value);
        }
        public HotObject Read(string name)
        {
            return this._hottype.Members.GetUnknown(_obj, name);
        }
        public object ReadObj(string name)
        {
            return this._hottype.Members.Get(_obj, name);
        }
        public Tout Read<Tout>(string name)
        {
            return this._hottype.Members.Get<Tout>(_obj, name);
        }
        public void Write<Tin>(string name, Tin value)
        {
            this._hottype.Members.Set(_obj, name, value);
        }
        public string FindMethodId(string name, params IHotParam[] _params)
        {
            return this._hottype.Methods.FindMethodId(name, _params);
        }
        public Tout CallByMethodId<Tout>(string id, params IHotParam[] _params)
        {
            return this._hottype.Methods.CallByMethodId<Tout>(_obj, id, _params);
        }
        public HotObject CallByMethodId(string id, params IHotParam[] _params)
        {
            return this._hottype.Methods.CallUnknownByMethodId(_obj, id, _params);
        }
        public Tout Call<Tout>(string name, params IHotParam[] _params)
        {
            var id = FindMethodId(name, _params);
            return CallByMethodId<Tout>(id, _params);
        }
        public HotObject Call(string name, params IHotParam[] _params)
        {
            var id = FindMethodId(name, _params);
            return CallByMethodId(id, _params);
        }
        public string FindEventId(string name)
        {
            return this._hottype.Events.FindEventId(name);
        }
        public void AddEventByEventId(string id, params IHotEvent[] events)
        {
            this._hottype.Events.AddByEventId(_obj, id, events);
        }
        public void RemoveEventByEventId(string id, params IHotEvent[] events)
        {
            this._hottype.Events.RemoveByEventId(_obj, id, events);
        }
        public HotObject InvokeEventByEventId(string id, params IHotParam[] _params)
        {
            return this._hottype.Events.RasieUnknownByEventId(_obj, id, _params);
        }
        public Tout InvokeEventByEventId<Tout>(string id, params IHotParam[] _params)
        {
            return this._hottype.Events.RasieByEventId<Tout>(_obj, id, _params);
        }
        public void AddEvent(string name, params IHotEvent[] events)
        {
            var id = FindEventId(name);
            AddEventByEventId(id, events);
        }
        public void RemoveEvent(string name, params IHotEvent[] events)
        {
            var id = FindEventId(name);
            RemoveEventByEventId(id, events);
        }
        public HotObject InvokeEvent(string name, params IHotParam[] _params)
        {
            var id = FindEventId(name);
            return InvokeEventByEventId(id, _params);
        }
        public Tout InvokeEvent<Tout>(string name, params IHotParam[] _params)
        {
            var id = FindEventId(name);
            return InvokeEventByEventId<Tout>(id, _params);
        }
        public virtual void Dispose()
        {
            if (this._hottype != null)
            {
                if (this._hottype.Methods.Exist("Dispose")) Call("Dispose");
                _hottype = null;
            }
            _obj = null;
        }
    }
}
